home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / MAILCLI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-07  |  8.1 KB  |  365 lines

  1. /* Mail Command Line Interface -- Clients
  2.  * Copyright 1992 William Allen Simpson
  3.  *    partly based on a MAIL client design by Anders Klemets, SM0RGV
  4.  *
  5.  * Mods by PA0GRI
  6.  * Improved param cracking
  7.  */
  8. #include "global.h"
  9. #include "ctype.h"
  10. #include <time.h>
  11. #include "timer.h"
  12. #include "proc.h"
  13. #include "socket.h"
  14. #include "domain.h"
  15. #include "cmdparse.h"
  16. #include "files.h"
  17. #include "netuser.h"
  18. #include "mailcli.h"
  19. #include "mailutil.h"
  20. #include "smtp.h"
  21.  
  22.  
  23. #if !defined(_lint)
  24. static char rcsid[] OPTIONAL = "$Id: mailcli.c,v 1.18 1997/09/07 21:18:28 root Exp root $";
  25. #endif
  26.  
  27. /* Tracing levels:
  28.     0 - no tracing
  29.     1 - serious errors reported
  30.     2 - transient errors reported
  31.     3 - session progress reported
  32.  */
  33. unsigned short Mailtrace = 1;
  34.  
  35. #ifdef MAILCLIENT
  36. int Mailquiet = FALSE;
  37.  
  38. #ifdef LZW
  39. int poplzw = TRUE;
  40. #endif
  41.  
  42. static struct mailservers *Mailservers = NULLMAIL;
  43.  
  44. static int domsquiet (int argc, char *argv[], void *p);
  45. static int domstrace (int argc, char *argv[], void *p);
  46. static int doadds (int argc, char *argv[], void *p);
  47. static int dodrops (int argc, char *argv[], void *p);
  48. static int dokicks (int argc, char *argv[], void *p);
  49. static int dolists (int argc, char *argv[], void *p);
  50. #ifdef LZW
  51. static int dopoplzw (int argc, char *argv[], void *p);
  52. #endif
  53. static void mailtick (void *tp);
  54.  
  55. static char mreaderr[] = "popmail: Missing";
  56.  
  57. static struct cmds Mailcmds[] =
  58. {
  59.     { "addserver",    doadds,        0, 2, "popmail addserver <mailserver> [<seconds>] [hh:mm-hh:mm] <protocol> <mailbox> <username> <password>" },
  60.     { "dropserver",    dodrops,    0, 2, "popmail dropserver <mailserver>" },
  61.     { "kick",    dokicks,    0, 2, "popmail kick <mailserver>" },
  62.     { "list",    dolists,    0, 0, NULLCHAR },
  63. #ifdef LZW
  64.     { "lzw",    dopoplzw,    0, 0, NULLCHAR },
  65. #endif
  66.     { "quiet",    domsquiet,    0, 0, NULLCHAR },
  67.     { "trace",    domstrace,    0, 0, NULLCHAR },
  68.     { NULLCHAR,    NULL,        0, 0, NULLCHAR }
  69. };
  70.  
  71.  
  72. #ifdef LZW
  73. static
  74. int 
  75. dopoplzw (int argc, char *argv[], void *p OPTIONAL)
  76. {
  77.     return setbool (&poplzw, "pop lzw", argc, argv);
  78. }
  79. #endif
  80.  
  81.  
  82. int
  83. domsread (int argc, char *argv[], void *p)
  84. {
  85.     return subcmd (Mailcmds, argc, argv, p);
  86. }
  87.  
  88.  
  89. static int
  90. domsquiet (int argc, char *argv[], void *p OPTIONAL)
  91. {
  92.     return setbool (&Mailquiet, "mail quiet", argc, argv);
  93. }
  94.  
  95.  
  96.  
  97. static int
  98. domstrace (int argc, char *argv[], void *p OPTIONAL)
  99. {
  100.     return setshort (&Mailtrace, "mail tracing", argc, argv);
  101. }
  102.  
  103.  
  104.  
  105. static int
  106. doadds (int argc, char *argv[], void *p OPTIONAL)
  107. {
  108. struct mailservers *np;
  109. char *fullname;
  110. int i = 2;
  111.  
  112.     fullname = domainsuffix (argv[1]);
  113.     if (resolve (fullname) == (uint32) 0) {
  114.         tprintf ("Unknown host %s\n", fullname);
  115.         /* domainsuffix() ALLOCATED memory !, so free it - WG7J */
  116.         free (fullname);
  117.         return 1;
  118.     }
  119.  
  120.     np = (struct mailservers *) callocw (1, sizeof (struct mailservers));
  121.  
  122.     np->hostname = fullname;
  123.     np->next = Mailservers;
  124.     Mailservers = np;
  125.     np->lowtime = np->hightime = -1;
  126.     np->timer.func = mailtick;    /* what to call on timeout */
  127.     np->timer.arg = (void *) np;
  128.  
  129.     if (argc > i && isdigit (*argv[i])) {
  130.         if (strchr (argv[i], '-') == NULLCHAR)
  131.             /* set timer duration */
  132.             set_timer (&np->timer, atol (argv[i++]) * 1000L);
  133.     }
  134.  
  135.     if (argc > i && isdigit (*argv[i])) {
  136.         int lh, ll, hh, hl;
  137.  
  138.         sscanf (argv[i++], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
  139.         np->lowtime = lh * 100 + ll;
  140.         np->hightime = hh * 100 + hl;
  141.     }
  142.  
  143.     if (argc > i) {
  144.         struct daemon *dp = Mailreaders;
  145.  
  146.         for (; dp->name != NULLCHAR; dp++) {
  147.             if (stricmp (dp->name, argv[i]) == 0) {
  148.                 np->reader = dp;
  149.                 break;
  150.             }
  151.         }
  152.         if (np->reader == NULLDAEMON) {
  153.             tprintf ("unrecognized protocol '%s'\n", argv[i]);
  154.             goto quit;
  155.         }
  156.         i++;
  157.     } else {
  158.         tprintf ("%s protocol\n", mreaderr);
  159.         goto quit;
  160.     }
  161.  
  162.     if (argc > i) {
  163.         np->mailbox = strdup (argv[i++]);
  164.     } else {
  165.         tprintf ("%s mailbox\n", mreaderr);
  166.         goto quit;
  167.     }
  168.  
  169.     if (argc > i) {
  170.         np->username = strdup (argv[i++]);
  171.     } else {
  172.         tprintf ("%s username\n", mreaderr);
  173.         goto quit;
  174.     }
  175.  
  176.     if (argc > i) {
  177.         np->password = strdup (argv[i++]);
  178.     } else {
  179.         tprintf ("%s password\n", mreaderr);
  180.         goto quit;
  181.     }
  182.  
  183.     start_detached_timer (&np->timer);    /* and fire it up */
  184.     return 0;
  185.  
  186. quit:
  187.     Mailservers = np->next;
  188.     free (np->hostname);
  189.     free (np->username);
  190.     free (np->password);
  191.     free (np->mailbox);
  192.     free ((char *) np);
  193.     return -1;
  194. }
  195.  
  196.  
  197. static int
  198. dodrops (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
  199. {
  200. struct mailservers *np, *npprev = NULLMAIL;
  201. char *fullname;
  202.  
  203.     fullname = domainsuffix (argv[1]);
  204.     for (np = Mailservers; np != NULLMAIL; npprev = np, np = np->next) {
  205.         if (strnicmp (np->hostname, fullname, strlen (fullname)) == 0) {
  206.             stop_timer (&np->timer);
  207.             free (np->hostname);
  208.             np->hostname = NULLCHAR;
  209.             free (np->username);
  210.             free (np->password);
  211.             free (np->mailbox);
  212.  
  213.             if (npprev != NULLMAIL)
  214.                 npprev->next = np->next;
  215.             else
  216.                 Mailservers = np->next;
  217.             free ((char *) np);
  218.             np = (struct mailservers *) 0;
  219.             free (fullname);
  220.             return 0;
  221.         }
  222.     }
  223.     tputs ("No such server enabled.\n");
  224.     free (fullname);
  225.     return -1;
  226. }
  227.  
  228.  
  229. static int
  230. dolists (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
  231. {
  232. struct mailservers *np;
  233.  
  234.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  235.         char tbuf[80];
  236.  
  237.         if (np->lowtime != -1 && np->hightime != -1)
  238.             sprintf (tbuf, " %02d:%02d-%02d:%02d",
  239.                  np->lowtime / 100,
  240.                  np->lowtime % 100,
  241.                  np->hightime / 100,
  242.                  np->hightime % 100);
  243.         else
  244.             tbuf[0] = '\0';
  245.         tprintf ("%-32s (%lu/%lu%s) %s %s\n",
  246.              np->hostname,
  247.              read_timer (&np->timer) / 1000L,
  248.              dur_timer (&np->timer) / 1000L,
  249.              tbuf,
  250.              np->reader->name,
  251.              np->username);
  252.     }
  253.     return 0;
  254. }
  255.  
  256.  
  257. static int
  258. dokicks (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
  259. {
  260. struct mailservers *np;
  261. char *fullname;
  262.  
  263.     fullname = domainsuffix (argv[1]);
  264.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  265.         if (strnicmp (np->hostname, fullname, strlen (fullname)) == 0) {
  266.             /* If the timer is not running, the timeout function
  267.              * has already been called, and we don't want to call
  268.              * it again.
  269.              */
  270. #if 0
  271.             if (np->timer.duration == 0 || run_timer (&np->timer)) {
  272. #endif
  273.                 stop_timer (&np->timer);
  274.                 (void) newproc (np->reader->name, np->reader->stksize,
  275.                         np->reader->fp, 0, np, NULL, 0);
  276. #if 0
  277.             }
  278. #endif
  279.             free (fullname);
  280.             return 0;
  281.         }
  282.     }
  283.     tputs ("No such server enabled.\n");
  284.     free (fullname);
  285.     return -1;
  286. }
  287.  
  288.  
  289. static void
  290. mailtick (void *tp)
  291. {
  292. struct mailservers *np = tp;
  293. struct tm *ltm;
  294. time_t t;
  295. int now;
  296.  
  297.     (void) time (&t);
  298.     ltm = localtime (&t);
  299.     now = ltm->tm_hour * 100 + ltm->tm_min;
  300.     if (np->lowtime < np->hightime) {    /* doesn't cross midnight */
  301.         if (now < np->lowtime || now >= np->hightime) {
  302.             if (Mailtrace >= 2)
  303.                 log (-1, "%s window to '%s' not open",
  304.                      np->reader->name,
  305.                      np->hostname);
  306.             start_detached_timer (&np->timer);
  307.             return;
  308.         }
  309.     } else {
  310.         if (now < np->lowtime && now >= np->hightime) {
  311.             if (Mailtrace >= 2)
  312.                 log (-1, "%s window to '%s' not open",
  313.                      np->reader->name,
  314.                      np->hostname);
  315.             start_detached_timer (&np->timer);
  316.             return;
  317.         }
  318.     }
  319.  
  320.     (void) newproc (np->reader->name, np->reader->stksize, np->reader->fp, 0, tp, NULL, 0);
  321. }
  322.  
  323.  
  324. int
  325. mailresponse (s, buf, comment)
  326. int s;                /* Socket index */
  327. char *buf;            /* User buffer */
  328. const char *comment;        /* comment for error message */
  329. {
  330.     if (recvline (s, (unsigned char *) buf, RLINELEN) != -1) {
  331.         if (Mailtrace >= 3) {
  332.             rip (buf);
  333.             log (s, "%s <== %s", comment, buf);
  334.         }
  335.         return 0;
  336.     }
  337.     if (Mailtrace >= 2)
  338.         log (s, "receive error for %s response", comment);
  339.     return -1;
  340. }
  341.  
  342.  
  343. /* Check to see if mailbox is already busy (or perpetually locked) */
  344. int
  345. mailbusy (struct mailservers *np)
  346. {
  347. int countdown = 10;
  348.  
  349.     while (mlock (Mailspool, np->mailbox)) {
  350.         if (--countdown > 0)
  351.             (void) kpause (60000L);    /* 60 seconds */
  352.         else {
  353.             start_detached_timer (&np->timer);
  354.             return TRUE;
  355.         }
  356.     }
  357.  
  358.     /* release while processing */
  359.     rmlock (Mailspool, np->mailbox);
  360.     return FALSE;
  361. }
  362.  
  363.  
  364. #endif /* MAILCLIENT */
  365.